security: bound archive member enumeration before materialization - #70
security: bound archive member enumeration before materialization#70seonghobae wants to merge 11 commits into
Conversation
📝 WalkthroughWalkthroughZIP 및 gzip/tar 아카이브에 사전 구조 검증과 리소스 제한을 추가했습니다. wheel은 중앙 디렉터리를 먼저 검사합니다. sdist는 tar 멤버를 스트리밍 순회하며 메타데이터와 특수 형식을 검증합니다. 관련 회귀 테스트와 릴리스 증거 문서를 갱신했습니다. Changes아카이브 검증 및 SBOM 생성
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant generate_release_sbom.py
participant ZIP preflight
participant zipfile
participant gzip/tar streaming validator
participant SBOM metadata extraction
generate_release_sbom.py->>ZIP preflight: wheel 중앙 디렉터리 사전 검사
ZIP preflight->>zipfile: 검증된 wheel 전달
zipfile->>SBOM metadata extraction: wheel 메타데이터 제공
generate_release_sbom.py->>gzip/tar streaming validator: sdist gzip/tar 물리 검사
gzip/tar streaming validator->>SBOM metadata extraction: 제한된 멤버 스트림 전달
Possibly related issues
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
|
@opencode-agent Implement the bounded GREEN repair on exact current RED head The immutable RED commit is valid. Local execution against the exact current generator failed only the two new focused regressions: the overmember wheel reached Modify only:
Required bounded implementation:
Run the two focused RED tests first, then all new boundary tests, the full Python 3.10–3.13 suite, Ruff, compileall, public-docstring checks, 100% production statement and branch coverage, product-guard self-test, wheel/sdist package acceptance, and applicable SAST/Security Scan on the resulting exact head. Keep the PR draft. Stop without writing if the head differs from |
|
@opencode-agent The earlier implementation request remains authoritative. To avoid any ambiguity and connector-size truncation, apply the exact verified four-file patch below on exact current RED head Patch contract:
Procedure: copy the base64 payload without whitespace to a root-only temporary file outside the repository, decode base64, verify the gzip SHA-256, decompress, verify decoded size and SHA-256, run |
|
@opencode-agent Apply and verify the exact patch payload in comment |
|
@coderabbitai review Please review exact current head |
🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
expected_head='eae6c374dcf58237c6c6e7cd9c12409c7d1425c3'
base='224e6d253a7957e981515ec66260fb1c2cf84a31'
printf '%s\n' '== HEAD =='
git rev-parse HEAD
git status --short
printf '%s\n' '== changed paths =='
git diff --name-status "$base"...HEAD
printf '%s\n' '== diff stat =='
git diff --stat "$base"...HEAD
printf '%s\n' '== module outline =='
ast-grep outline scripts/ci/generate_release_sbom.py --items all --type function --view expanded
printf '%s\n' '== boundary test outline =='
ast-grep outline tests/test_release_sbom_member_enumeration_bound.py --items all --type function --view expanded
printf '%s\n' '== materialization and parser call sites =='
rg -n -C 4 -P '\b(ZipFile|infolist|getmembers|tarfile\.open|open_archive|r:gz|r\|gz)\b' \
scripts/ci/generate_release_sbom.py tests/test_release_sbom_member_enumeration_bound.py
printf '%s\n' '== target diff =='
git diff --find-renames --find-copies --unified=50 "$base"...HEAD -- \
scripts/ci/generate_release_sbom.py \
tests/test_release_sbom_member_enumeration_bound.py \
docs/sbom-release-evidence.md \
CHANGELOG.mdLength of output: 90303 🏁 Script executed: #!/bin/bash
set -euo pipefail
printf '%s\n' '== bounded descriptor reader and artifact flow =='
nl -ba scripts/ci/generate_release_sbom.py | sed -n '55,175p'
printf '%s\n' '== ZIP preflight implementation =='
nl -ba scripts/ci/generate_release_sbom.py | sed -n '215,355p'
printf '%s\n' '== gzip/tar preflight and streaming semantics =='
nl -ba scripts/ci/generate_release_sbom.py | sed -n '345,535p'
printf '%s\n' '== helper call sites and potentially unbounded reads =='
rg -n -C 3 -P '\b(_preflight_wheel_members|_preflight_sdist_members|_read_expanded|\.read\s*\(\s*\)|\.read\s*\(\s*-1\s*\)|getmembers\s*\()' \
scripts/ci/generate_release_sbom.py tests --glob '*.py'
printf '%s\n' '== test and coverage configuration =='
fd -HI -t f '^(pyproject\.toml|pytest\.ini|setup\.cfg|tox\.ini|\.coveragerc)$' . \
-x sh -c 'echo "---- $1"; cat "$1"' sh {}
printf '%s\n' '== existing generator test references =='
rg -n -C 2 -P '\b(build_sbom|_wheel_metadata|_sdist_metadata|generate_release_sbom)\b' \
tests --glob '*.py'
printf '%s\n' '== changed-line coverage markers, if present =='
rg -n -C 2 -P '(pragma:\s*no cover|coverage|branch)' \
scripts/ci/generate_release_sbom.py tests/test_release_sbom_member_enumeration_bound.pyLength of output: 1630 🏁 Script executed: #!/bin/bash
set -euo pipefail
show_range() {
file="$1"
start="$2"
end="$3"
awk -v start="$start" -v end="$end" \
'NR >= start && NR <= end { printf "%6d %s\n", NR, $0 }' "$file"
}
printf '%s\n' '== bounded descriptor reader and artifact flow =='
show_range scripts/ci/generate_release_sbom.py 55 175
printf '%s\n' '== ZIP preflight implementation =='
show_range scripts/ci/generate_release_sbom.py 215 355
printf '%s\n' '== gzip/tar preflight and streaming semantics =='
show_range scripts/ci/generate_release_sbom.py 345 535
printf '%s\n' '== helper call sites and potentially unbounded reads =='
rg -n -C 3 -P '\b(_preflight_wheel_members|_preflight_sdist_members|_read_expanded|\.read\s*\(\s*\)|\.read\s*\(\s*-1\s*\)|getmembers\s*\()' \
scripts/ci/generate_release_sbom.py tests --glob '*.py'
printf '%s\n' '== test and coverage configuration =='
while IFS= read -r file; do
printf '%s\n' "---- $file"
cat "$file"
done < <(fd -HI -t f '^(pyproject\.toml|pytest\.ini|setup\.cfg|tox\.ini|\.coveragerc)$' .)
printf '%s\n' '== existing generator test references =='
rg -n -C 2 -P '\b(build_sbom|_wheel_metadata|_sdist_metadata|generate_release_sbom)\b' \
tests --glob '*.py'
printf '%s\n' '== changed-line coverage markers, if present =='
rg -n -C 2 -P '(pragma:\s*no cover|coverage|branch)' \
scripts/ci/generate_release_sbom.py tests/test_release_sbom_member_enumeration_bound.py || trueLength of output: 44381 🏁 Script executed: #!/bin/bash
set -euo pipefail
printf '%s\n' '== repository test and coverage configuration files =='
find . -type f \( \
-name pyproject.toml -o -name pytest.ini -o -name setup.cfg -o \
-name tox.ini -o -name .coveragerc \
\) -print | sort | while IFS= read -r file; do
printf '%s\n' "---- $file"
cat "$file"
done
printf '%s\n' '== existing bounded-reader regression coverage =='
awk 'NR >= 250 && NR <= 380 { printf "%6d %s\n", NR, $0 }' \
tests/test_release_sbom_archive_bound.py
printf '%s\n' '== all release-SBOM test modules =='
find tests -maxdepth 1 -type f -name '*release_sbom*.py' -print | sort
printf '%s\n' '== test assertions for new public errors and parser ordering =='
rg -n -C 2 -P \
'(ZipFile materialized|tarfile\.open|archive-member safety bound|expanded-tar safety bound|extension header exceeds|not a valid (ZIP|gzip tar))' \
tests/test_release_sbom_member_enumeration_bound.py tests/test_release_sbom_archive_bound.py
printf '%s\n' '== diff whitespace and exact changed-path check =='
git diff --check 224e6d253a7957e981515ec66260fb1c2cf84a31...HEAD
git diff --name-only 224e6d253a7957e981515ec66260fb1c2cf84a31...HEAD | sortLength of output: 14937
I found one issue.
The static implementation review found that:
|
|
@opencode-agent Apply one bounded changelog-only completion to exact current head Modify only Under Do not change code, tests, docs, |
|
@coderabbitai review Retry the exact-head review for |
|
✅ Action performedReview finished.
|
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
tests/test_release_sbom_member_enumeration_bound.py (1)
159-165: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win
MAX_ARCHIVE_MEMBERS도 이 상수 고정 테스트에 포함하십시오.
test_new_archive_bounds_are_exact는MAX_EXPANDED_TAR_BYTES,MAX_TAR_EXTENSION_BYTES,ZIP64_EOCD_LOCATOR_SIZE만 확인합니다.EXPECTED_MAX_ARCHIVE_MEMBERS는 fixture 크기 계산에만 사용됩니다. 생성기에서MAX_ARCHIVE_MEMBERS가 변경되면 fixture 멤버 수만 어긋나고 이 테스트는 계속 통과합니다. 두 값의 일치를 명시적으로 고정하십시오.♻️ 제안 수정
assert generator.MAX_EXPANDED_TAR_BYTES == 512 * 1024 * 1024 assert generator.MAX_TAR_EXTENSION_BYTES == 1 * 1024 * 1024 assert generator.ZIP64_EOCD_LOCATOR_SIZE == 20 + assert generator.MAX_ARCHIVE_MEMBERS == EXPECTED_MAX_ARCHIVE_MEMBERS🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@tests/test_release_sbom_member_enumeration_bound.py` around lines 159 - 165, Update test_new_archive_bounds_are_exact to also assert generator.MAX_ARCHIVE_MEMBERS equals EXPECTED_MAX_ARCHIVE_MEMBERS, explicitly locking the generator limit to the fixture’s expected member count while preserving the existing constant checks.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@scripts/ci/generate_release_sbom.py`:
- Around line 434-437: Update the exception handling around gzip.GzipFile.read()
to import zlib and include zlib.error alongside OSError and EOFError, while
preserving the existing SystemExit passthrough and normalization to
SystemExit(invalid).
---
Nitpick comments:
In `@tests/test_release_sbom_member_enumeration_bound.py`:
- Around line 159-165: Update test_new_archive_bounds_are_exact to also assert
generator.MAX_ARCHIVE_MEMBERS equals EXPECTED_MAX_ARCHIVE_MEMBERS, explicitly
locking the generator limit to the fixture’s expected member count while
preserving the existing constant checks.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 00098112-9592-47d4-95b0-ca7520d3f0d1
📒 Files selected for processing (4)
CHANGELOG.mddocs/sbom-release-evidence.mdscripts/ci/generate_release_sbom.pytests/test_release_sbom_member_enumeration_bound.py
|
@opencode-agent Apply the exact-head review-test repair on branch Modify only
Run the focused test module. Do not modify any other path, workflow, dependency, credential, permission, ref, base, PR state, release behavior, or publication behavior. Do not rebase, retarget, mark ready, merge, or enable auto-merge. Stop without writing if the exact head differs. |
|
@coderabbitai review Review exact current head |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
expected_head='24fbe1f9acb0489e9c628db23f9fe3612ef3112a'
base='224e6d253a7957e981515ec66260fb1c2cf84a31'
actual_head="$(git rev-parse HEAD)"
printf 'HEAD=%s\n' "$actual_head"
if [ "$actual_head" != "$expected_head" ]; then
printf 'ERROR: expected exact head %s\n' "$expected_head" >&2
exit 2
fi
printf '\n== Changed paths ==\n'
git diff --name-status "$base...$expected_head"
printf '\n== Diff check ==\n'
git diff --check "$base...$expected_head"
printf '\n== Targeted implementation outline ==\n'
ast-grep outline scripts/ci/generate_release_sbom.py --items all --type function --view expanded
printf '\n== Targeted test outline ==\n'
ast-grep outline tests/test_release_sbom_member_enumeration_bound.py --items all --type function --view expanded
printf '\n== Parser, decompression, and bounded-read call sites ==\n'
rg -n -C 5 -P '\b(ZipFile|infolist|getmembers|tarfile\.open|r:gz|r\|gz|zlib\.error|gzip\.(BadGzipFile|GzipFile)|_preflight_(wheel|sdist)_members|MAX_ARCHIVE_MEMBERS|MAX_EXPANDED_TAR_BYTES|MAX_TAR_EXTENSION_BYTES|_read_expanded)\b' \
scripts/ci/generate_release_sbom.py \
tests/test_release_sbom_member_enumeration_bound.py
printf '\n== Implementation: archive preflight and semantic parser ==\n'
nl -ba scripts/ci/generate_release_sbom.py | sed -n '1,620p'
printf '\n== Test: repaired regression and neighboring checks ==\n'
rg -n -C 18 -P 'def test_(new_archive_bounds_are_exact|tar_preflight_normalizes_gzip_errors_and_rewinds|wheel_member_bound_precedes_zipfile_materialization|sdist_member_bound_does_not_materialize_getmembers|canonical_wheel_and_sdist_remain_compatible)' \
tests/test_release_sbom_member_enumeration_bound.py
printf '\n== Four-file diff ==\n'
git diff --find-renames --find-copies --unified=35 "$base...$expected_head" -- \
CHANGELOG.md \
docs/sbom-release-evidence.md \
scripts/ci/generate_release_sbom.py \
tests/test_release_sbom_member_enumeration_bound.py
printf '\n== Coverage configuration ==\n'
fd -HI -t f '^(pyproject\.toml|pytest\.ini|setup\.cfg|tox\.ini|\.coveragerc)$' . \
-x sh -c 'printf "\\n---- %s ----\\n" "$1"; cat "$1"' sh {}Length of output: 42455 🏁 Script executed: #!/bin/bash
set -euo pipefail
expected_head='24fbe1f9acb0489e9c628db23f9fe3612ef3112a'
base='224e6d253a7957e981515ec66260fb1c2cf84a31'
test "$(git rev-parse HEAD)" = "$expected_head"
show_range() {
file="$1"
start="$2"
end="$3"
printf '\n== %s, lines %s-%s ==\n' "$file" "$start" "$end"
awk -v start="$start" -v end="$end" \
'NR >= start && NR <= end { printf "%6d %s\n", NR, $0 }' "$file"
}
show_range scripts/ci/generate_release_sbom.py 55 175
show_range scripts/ci/generate_release_sbom.py 219 445
show_range scripts/ci/generate_release_sbom.py 443 540
show_range tests/test_release_sbom_member_enumeration_bound.py 1 390
printf '\n== Semantic tar parser exception handling and unbounded APIs ==\n'
rg -n -C 8 -P \
'except\s+\(|except\s+.*zlib\.error|tarfile\.open|for\s+member\s+in\s+archive|extractfile|\.read\s*\(\s*\)|getmembers\s*\(' \
scripts/ci/generate_release_sbom.py
printf '\n== Documentation and changelog diff ==\n'
git diff --unified=30 "$base...$expected_head" -- CHANGELOG.md docs/sbom-release-evidence.md
printf '\n== Production and test diff ==\n'
git diff --unified=20 "$base...$expected_head" -- \
scripts/ci/generate_release_sbom.py \
tests/test_release_sbom_member_enumeration_bound.py
printf '\n== Coverage configuration ==\n'
for file in $(find . -type f \( -name pyproject.toml -o -name pytest.ini -o -name setup.cfg -o -name tox.ini -o -name .coveragerc \) -print | sort); do
printf '\n---- %s ----\n' "$file"
cat "$file"
done
printf '\n== Historical coverage-related changes in this PR ==\n'
git diff --name-status "$base...$expected_head" -- \
pyproject.toml pytest.ini setup.cfg tox.ini .coveragercLength of output: 104385
I found one issue.
I confirmed the stated repairs:
I did not execute tests, CI, lint, packaging, or security checks. These gates remain pending. You are interacting with an AI system. |
|
@coderabbitai review Review exact current head |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
expected_head='e2c3db6850c055f6ae5f904e00b1ca389a788cd1'
base='224e6d253a7957e981515ec66260fb1c2cf84a31'
actual_head="$(git rev-parse HEAD)"
printf 'HEAD=%s\n' "$actual_head"
if [ "$actual_head" != "$expected_head" ]; then
printf 'ERROR: expected exact head %s\n' "$expected_head" >&2
exit 2
fi
printf '\n== Changed paths ==\n'
git diff --name-status "$base...$expected_head"
printf '\n== Changed path count ==\n'
git diff --name-only "$base...$expected_head" | wc -l
printf '\n== Diff check ==\n'
git diff --check "$base...$expected_head"
printf '\n== Coverage configuration ==\n'
fd -HI -t f '^(pyproject\.toml|pytest\.ini|setup\.cfg|tox\.ini|\.coveragerc)$' . \
-x sh -c 'printf "\n---- %s ----\n" "$1"; cat "$1"' sh {}
printf '\n== Archive generator outline ==\n'
ast-grep outline scripts/ci/generate_release_sbom.py --items all --type function --view expanded
printf '\n== Archive boundary test outline ==\n'
ast-grep outline tests/test_release_sbom_member_enumeration_bound.py --items all --type function --view expanded
printf '\n== Archive parser and coverage call sites ==\n'
rg -n -C 5 -P '\b(ZipFile|infolist|getmembers|tarfile\.open|r:gz|r\|gz|zlib\.error|gzip\.(BadGzipFile|GzipFile)|_preflight_(wheel|sdist)_members|MAX_ARCHIVE_MEMBERS|MAX_EXPANDED_TAR_BYTES|MAX_TAR_EXTENSION_BYTES|source_dirs|source\s*=|coverage)\b' \
pyproject.toml scripts/ci/generate_release_sbom.py tests/test_release_sbom_member_enumeration_bound.py
printf '\n== Five-file diff ==\n'
git diff --find-renames --find-copies --unified=35 "$base...$expected_head" -- \
CHANGELOG.md \
docs/sbom-release-evidence.md \
pyproject.toml \
scripts/ci/generate_release_sbom.py \
tests/test_release_sbom_member_enumeration_bound.pyLength of output: 104345 🏁 Script executed: #!/bin/bash
set -euo pipefail
expected_head='e2c3db6850c055f6ae5f904e00b1ca389a788cd1'
test "$(git rev-parse HEAD)" = "$expected_head"
show_range() {
file="$1"
start="$2"
end="$3"
printf '\n== %s, lines %s-%s ==\n' "$file" "$start" "$end"
awk -v start="$start" -v end="$end" \
'NR >= start && NR <= end { printf "%6d %s\n", NR, $0 }' "$file"
}
show_range scripts/ci/generate_release_sbom.py 378 540
show_range scripts/ci/generate_release_sbom.py 750 845
show_range tests/test_release_sbom_member_enumeration_bound.py 271 368
printf '\n== Python files under scripts/ci ==\n'
fd -t f -e py . scripts/ci | sort
printf '\n== Coverage commands and source-directory references ==\n'
rg -n -C 4 -P '(coverage(\s+run|\s+report|\s+combine)?|pytest|source_dirs|generate_release_sbom)' \
.github scripts README.md docs pyproject.toml \
-g '*.yml' -g '*.yaml' -g '*.md' -g '*.toml' -g '*.py' 2>/dev/null || true
printf '\n== Tests that load or execute each scripts/ci Python module ==\n'
for file in $(fd -t f -e py . scripts/ci | sort); do
name="$(basename "$file" .py)"
printf '\n---- %s ----\n' "$file"
rg -n -C 2 -P "(${name//./\\.}|${file//\//\\/})" tests --glob '*.py' || true
done
printf '\n== Tar semantic exception paths ==\n'
rg -n -C 8 -P 'def _sdist_metadata|except tarfile\.TarError|except \(.*zlib\.error|tarfile\.open|extractfile|selected_payload|_sha256_file|_artifact_metadata|build_sbom' \
scripts/ci/generate_release_sbom.py
printf '\n== Changed coverage configuration validation context ==\n'
git show "$expected_head:pyproject.toml" | sed -n '65,82p'Length of output: 55378 🏁 Script executed: #!/bin/bash
set -euo pipefail
expected_head='e2c3db6850c055f6ae5f904e00b1ca389a788cd1'
test "$(git rev-parse HEAD)" = "$expected_head"
printf '%s\n' '== Hourly guard outline =='
ast-grep outline scripts/ci/hourly_product_guard.py --items all --view expanded
printf '%s\n' '== Hourly guard executable entry points =='
rg -n -C 5 -P '^(def |class |if __name__|[[:space:]]*raise SystemExit|[[:space:]]*main\()' \
scripts/ci/hourly_product_guard.py
printf '%s\n' '== References to hourly product guard in tests and coverage startup =='
rg -n -C 3 -P '(hourly_product_guard|COVERAGE_PROCESS_START|coverage\.process_startup|coverage run|coverage report)' \
tests .github pyproject.toml \
-g '*.py' -g '*.yml' -g '*.yaml' -g '*.toml' || true
printf '%s\n' '== Coverage configuration files =='
fd -HI -t f '^(pyproject\.toml|\.coveragerc|setup\.cfg|tox\.ini|sitecustomize\.py)$' . \
-x sh -c 'printf "\n---- %s ----\n" "$1"; cat "$1"' sh {}Length of output: 14031
I found one issue.
I confirmed the earlier repairs:
I did not execute tests, CI, lint, package acceptance, or security checks. These checks remain pending. You are interacting with an AI system. |
|
@coderabbitai review @opencode-agent Perform a read-only review of exact current head Treat all checks and reviews on The recorded stacked base remains |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
expected_head='b8526736db3bb16ed88290ca64fd07cf54232805'
base='224e6d253a7957e981515ec66260fb1c2cf84a31'
actual_head="$(git rev-parse HEAD)"
printf 'HEAD=%s\n' "$actual_head"
if [ "$actual_head" != "$expected_head" ]; then
printf 'ERROR: expected exact head %s\n' "$expected_head" >&2
exit 2
fi
printf '\n== Status and changed paths from recorded base ==\n'
git status --short
git diff --name-status "$base...$expected_head"
printf '\n== Whitespace check ==\n'
git diff --check "$base...$expected_head"
printf '\n== Configuration and workflow files ==\n'
fd -HI -t f '^(pyproject\.toml|.*\.(yml|yaml))$' . .github 2>/dev/null | sort
printf '\n== Coverage configuration ==\n'
sed -n '1,180p' pyproject.toml
printf '\n== Archive generator outline ==\n'
ast-grep outline scripts/ci/generate_release_sbom.py --items all --type function --view expanded
printf '\n== Archive boundary test outline ==\n'
ast-grep outline tests/test_release_sbom_member_enumeration_bound.py --items all --type function --view expanded
printf '\n== Archive and descriptor control call sites ==\n'
rg -n -C 5 -P '\b(ZipFile|infolist|getmembers|tarfile\.open|r:gz|r\|gz|zlib\.error|_preflight_(wheel|sdist)_members|MAX_ARCHIVE_MEMBERS|MAX_EXPANDED_TAR_BYTES|MAX_TAR_EXTENSION_BYTES|_read_expanded|sha256|stat|open)\b' \
scripts/ci/generate_release_sbom.py \
tests/test_release_sbom_member_enumeration_bound.py
printf '\n== CI workflow integration and coverage command call sites ==\n'
rg -n -C 6 -P '(workflow_call|uses:.*\.github/workflows|hourly_product_guard|coverage(\s+run|\s+report|\s+combine)?|source_dirs|protected|main)' \
.github pyproject.toml \
-g '*.yml' -g '*.yaml' -g '*.toml'
printf '\n== Five-file implementation diff ==\n'
git diff --find-renames --find-copies --unified=35 "$base...$expected_head" -- \
CHANGELOG.md \
docs/sbom-release-evidence.md \
pyproject.toml \
scripts/ci/generate_release_sbom.py \
tests/test_release_sbom_member_enumeration_bound.py
printf '\n== Pull request and referenced PR metadata ==\n'
gh pr view 70 --json number,state,isDraft,headRefOid,baseRefOid,mergeStateStatus,statusCheckRollup,url
gh pr view 68 --json number,state,isDraft,headRefOid,baseRefOid,mergeStateStatus,urlLength of output: 148137 🏁 Script executed: #!/bin/bash
set -euo pipefail
expected_head='b8526736db3bb16ed88290ca64fd07cf54232805'
base='224e6d253a7957e981515ec66260fb1c2cf84a31'
test "$(git rev-parse HEAD)" = "$expected_head"
show_range() {
file="$1"
start="$2"
end="$3"
printf '\n== %s, lines %s-%s ==\n' "$file" "$start" "$end"
awk -v start="$start" -v end="$end" \
'NR >= start && NR <= end { printf "%6d %s\n", NR, $0 }' "$file"
}
printf '== Diff for the coverage contract test ==\n'
git diff --unified=50 "$base...$expected_head" -- tests/test_quality_contracts.py
printf '\n== scripts/ci Python modules ==\n'
fd -t f -e py . scripts/ci | sort
printf '\n== Tests that load, import, or execute each scripts/ci module ==\n'
for file in $(fd -t f -e py . scripts/ci | sort); do
module="$(basename "$file" .py)"
printf '\n---- %s ----\n' "$file"
rg -n -C 3 -P "(${module}|${file//\//\\/})" tests --glob '*.py' || true
done
show_range scripts/ci/generate_release_sbom.py 55 175
show_range scripts/ci/generate_release_sbom.py 219 445
show_range scripts/ci/generate_release_sbom.py 443 540
show_range scripts/ci/generate_release_sbom.py 750 890
printf '\n== Archive API calls and exception handlers ==\n'
rg -n -C 7 -P \
'(except |ZipFile|infolist|getmembers|tarfile\.open|extractfile|\.read\s*\(\s*\)|_preflight_|_sha256_file|_require_live_artifact_descriptor)' \
scripts/ci/generate_release_sbom.py
printf '\n== Quality contract test source ==\n'
cat -n tests/test_quality_contracts.py
printf '\n== Documentation integration, archive controls, and references ==\n'
rg -n -C 3 -P \
'(protected-main|organization-level reusable|resource bound|ZipFile|ZIP64|multi-disk|512 MiB|1 MiB|getmembers|CWE-409|CWE-770|Python 3\.13)' \
docs/sbom-release-evidence.md CHANGELOG.md
printf '\n== Current PR checks, workflow runs, and mergeability metadata ==\n'
gh pr view 70 --json headRefOid,isDraft,mergeStateStatus,statusCheckRollup,url
gh run list --branch security/bound-archive-member-enumeration --limit 20 \
--json databaseId,headSha,name,status,conclusion,event,url,createdAtLength of output: 88084
I found one issue.
I confirmed these items by static inspection:
The diff from the recorded base changes six files, not five. The added file is I did not execute repository code, tests, CI, packaging, lint, or security scans. No You are interacting with an AI system. |
|
@coderabbitai review Review only exact current head Recheck the complete finite-resource archive boundary, including bounded wheel central-directory preflight before |
🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
expected_head='56c9029588b67f329c334b4e56e1361087f8f651'
base='224e6d253a7957e981515ec66260fb1c2cf84a31'
actual_head="$(git rev-parse HEAD)"
printf 'HEAD=%s\n' "$actual_head"
if [ "$actual_head" != "$expected_head" ]; then
printf 'ERROR: expected exact head %s\n' "$expected_head" >&2
exit 2
fi
printf '\n== Repository status and changed paths ==\n'
git status --short
git diff --name-status "$base...$expected_head"
printf '\n== Diff check ==\n'
git diff --check "$base...$expected_head"
printf '\n== Exact-head delta from superseded head ==\n'
git diff --name-status 'b8526736db3bb16ed88290ca64fd07cf54232805...$expected_head'
git diff --unified=20 'b8526736db3bb16ed88290ca64fd07cf54232805...$expected_head'
printf '\n== Coverage and protected-integration contract ==\n'
sed -n '60,95p' pyproject.toml
rg -n -C 4 -F 'protected-main or organization-level reusable workflow' \
docs/sbom-release-evidence.md tests/test_quality_contracts.py
printf '\n== Archive generator outline ==\n'
ast-grep outline scripts/ci/generate_release_sbom.py --items all --type function --view expanded
printf '\n== Archive-boundary test outline ==\n'
ast-grep outline tests/test_release_sbom_member_enumeration_bound.py --items all --type function --view expanded
printf '\n== Archive controls and parser call sites ==\n'
rg -n -C 5 -P '\b(ZipFile|infolist|getmembers|tarfile\.open|r:gz|r\|gz|zlib\.error|_preflight_(wheel|sdist)_members|MAX_ARCHIVE_MEMBERS|MAX_EXPANDED_TAR_BYTES|MAX_TAR_EXTENSION_BYTES|_read_expanded|_sha256_file|_require_live_artifact_descriptor)\b' \
scripts/ci/generate_release_sbom.py \
tests/test_release_sbom_member_enumeration_bound.py
printf '\n== Full target diff ==\n'
git diff --find-renames --find-copies --unified=30 "$base...$expected_head" -- \
CHANGELOG.md \
docs/sbom-release-evidence.md \
pyproject.toml \
scripts/ci/generate_release_sbom.py \
tests/test_release_sbom_member_enumeration_bound.py \
tests/test_quality_contracts.py
printf '\n== Workflow and sensitive-path changes ==\n'
git diff --name-only "$base...$expected_head" -- .github
git diff --name-only "$base...$expected_head" | rg -n '(^|/)(credentials?|secrets?|.*\.pem|.*\.key)$' || true
printf '\n== Exact-head PR state and workflow runs ==\n'
gh pr view 70 --json headRefOid,isDraft,mergeStateStatus,statusCheckRollup,url
gh run list --branch security/bound-archive-member-enumeration --limit 20 \
--json databaseId,headSha,name,status,conclusion,event,url,createdAtLength of output: 3404 🏁 Script executed: #!/bin/bash
set -euo pipefail
expected_head='56c9029588b67f329c334b4e56e1361087f8f651'
base='224e6d253a7957e981515ec66260fb1c2cf84a31'
superseded_head='b8526736db3bb16ed88290ca64fd07cf54232805'
test "$(git rev-parse HEAD)" = "$expected_head"
printf '\n== Exact-head delta from superseded head ==\n'
git diff --name-status "${superseded_head}...${expected_head}"
git diff --unified=20 "${superseded_head}...${expected_head}" -- \
docs/sbom-release-evidence.md \
CHANGELOG.md \
pyproject.toml \
scripts/ci/generate_release_sbom.py \
tests/test_quality_contracts.py \
tests/test_release_sbom_member_enumeration_bound.py
printf '\n== Coverage and protected-integration contract ==\n'
sed -n '60,95p' pyproject.toml
rg -n -C 5 -F 'protected-main or organization-level reusable workflow' \
docs/sbom-release-evidence.md tests/test_quality_contracts.py
printf '\n== ZIP preflight and descriptor controls ==\n'
sed -n '55,175p;215,355p' scripts/ci/generate_release_sbom.py
printf '\n== Tar preflight and sequential semantic parser ==\n'
sed -n '345,555p;750,890p' scripts/ci/generate_release_sbom.py
printf '\n== Unsafe or unbounded archive API call sites ==\n'
rg -n -C 5 -P '\b(getmembers|infolist|ZipFile|tarfile\.open|r:gz|r\|gz|zlib\.error|\.read\s*\(\s*\)|\.read\s*\(\s*-1\s*\))' \
scripts/ci/generate_release_sbom.py \
tests/test_release_sbom_member_enumeration_bound.py
printf '\n== Boundary-test assertions ==\n'
rg -n -C 10 -P \
'def test_(new_archive_bounds_are_exact|wheel_member_bound_precedes_zipfile_materialization|sdist_member_bound_does_not_materialize_getmembers|canonical_wheel_and_sdist_remain_compatible|tar_preflight_normalizes_gzip_errors_and_rewinds|tar_extension_and_expansion_limits_precede_semantic_parser)' \
tests/test_release_sbom_member_enumeration_bound.py
printf '\n== Changed workflow and sensitive paths ==\n'
git diff --name-only "$base...$expected_head" -- .github
git diff --name-only "$base...$expected_head" | rg '(^|/)(credentials?|secrets?|.*\.pem|.*\.key)$' || true
printf '\n== PR state and exact-head runs ==\n'
gh pr view 70 --json headRefOid,isDraft,mergeStateStatus,statusCheckRollup,url
gh run list --branch security/bound-archive-member-enumeration --limit 30 \
--json databaseId,headSha,name,status,conclusion,event,url,createdAtLength of output: 53131 🏁 Script executed: #!/bin/bash
set -euo pipefail
expected_head='56c9029588b67f329c334b4e56e1361087f8f651'
test "$(git rev-parse HEAD)" = "$expected_head"
printf '== Zero-block handling in implementation and tests ==\n'
rg -n -C 12 -P \
'(zero_headers|b"\\x00" \* 512|b"\\x00" \* 1024|trailing|end-of-archive|end of archive|physical header)' \
scripts/ci/generate_release_sbom.py \
tests/test_release_sbom_member_enumeration_bound.py \
docs/sbom-release-evidence.md
printf '\n== Tar fixture helpers and malformed-input tests ==\n'
sed -n '120,370p' tests/test_release_sbom_member_enumeration_bound.py
printf '\n== Semantic parsing exception and EOF paths ==\n'
sed -n '455,540p' scripts/ci/generate_release_sbom.py
printf '\n== Relevant Python tarfile documentation or installed stdlib source ==\n'
python3 - <<'PY'
import inspect
import tarfile
print(inspect.getsource(tarfile.TarFile.next))
PYLength of output: 35238
I found one issue.
I confirmed these items by static inspection:
No CI workflow run targets this exact head. Earlier failed CI runs apply only to earlier heads. I did not infer exact-head CI success.
|
|
@opencode-agent Fix the exact-current-head CodeRabbit finding on PR #70 test-first, and do nothing if the branch head is no longer The valid finding is in exact-head review: Use two auditable commits in this order:
Allowed paths only: After GREEN, run the focused regression plus the repository’s complete Python 3.10–3.13-compatible test/quality contract, Ruff, compileall, public-docstring contract, 100% production statement and branch coverage, and package acceptance available locally. Keep PR #70 draft because its stacked base has diverged. Report exact RED and GREEN SHAs in the PR conversation, and request a fresh CodeRabbit review bound to the GREEN SHA without claiming missing hosted checks as success. |
|
@opencode-agent Implement the newly confirmed CodeRabbit finding test-first on exact current head The exact-head review found one valid fail-closed tar-boundary defect: the physical gzip/tar preflight resets Required RED → GREEN sequence:
Do not modify |
Test-first parser-resource hardening
Progresses #69 as a bounded draft stack on PR #68.
Exact tree binding
224e6d253a7957e981515ec66260fb1c2cf84a31.127e4577ea31ca20e7260a482343c892efeed6f9.fb4ccefae3899c617bf969a3c93be3924177b23c.24fbe1f9acb0489e9c628db23f9fe3612ef3112a.e2c3db6850c055f6ae5f904e00b1ca389a788cd1.b8526736db3bb16ed88290ca64fd07cf54232805.56c9029588b67f329c334b4e56e1361087f8f651.PR #68 advanced after this stack was created. No rebase, retarget, force update, automatic conflict strategy, or credential-bearing tree publication has been used. The stack remains draft until an auditable credential-separated integration mechanism reconstructs and independently verifies the exact intended tree.
Confirmed gap and immutable RED evidence
The direct generator enforced the 256 MiB compressed-byte ceiling before and during parser reads, but the archive-member limit was evaluated after parser materialization:
zipfile.ZipFile(stream)built the complete central-directoryZipInfotable beforeinfolist()reached the repository member check; andtarfile.getmembers()constructed the complete tar member list before that check.CI run
31104663109is the immutable RED evidence onfb4ccefae3899c617bf969a3c93be3924177b23c: package acceptance and Ruff passed; every Python 3.10–3.13 lane failed only the two focused regressions, with Python 3.13 reporting2 failed, 763 passed.Bounded implementation
The current change:
ZipFileallocation, enforcing exact EOCD record/count/size/offset agreement and the 10,000-member limit;getmembers()materialization with sequentialr|gzparsing that retains only the bounded seen-name set and one rootPKG-INFOpayload;zlib.errorwithout traceback leakage and locksMAX_ARCHIVE_MEMBERSto the overmember fixtures following CodeRabbit review;scripts/ciin the repository production statement and branch coverage source directories, with the repository contract test bound to that exact configuration;[Unreleased]Security entry without a version bump.Contract-repair evidence
CI run
31121580673completed with failure on exact heade2c3db6850c055f6ae5f904e00b1ca389a788cd1. Package acceptance and Ruff succeeded. Python 3.10, 3.12, and 3.13 reached the suite and failed only two stale repository-contract expectations; Python 3.13 reported2 failed, 778 passed. The Python 3.11 runner failed during job setup and is not test acceptance evidence.The two reproducible contract failures were repaired without weakening production behavior:
393a125171dbd797a6bfcdcaafaf83b814d86aeebindstests/test_quality_contracts.pyto the intendedsource_dirs = ["src/egressweave", "scripts/ci"]statement-and-branch coverage scope; andb8526736db3bb16ed88290ca64fd07cf54232805restored the protected integration wording required bytests/test_release_contracts.pysemantically, but line-wrapped the literal contract phrase.Pull-request CI run
31125435331then completed failure on exact headb8526736db3bb16ed88290ca64fd07cf54232805. Package acceptance and Ruff succeeded; the Python lanes failed the release-contract assertion because the documentation split the required literal phraseprotected-main or organization-level reusable workflowacross a line break. That is a documentation-contract failure, not successful acceptance evidence.Exact current commit
56c9029588b67f329c334b4e56e1361087f8f651changes only that documentation wrapping, preserving the implementation, tests, standards references, changelog, and protected integration semantics. No pull-request workflow run is currently associated with this exact head, so no exact-current-head CI or security success is claimed.Review state and remaining gates
The prior CodeRabbit findings for
zlib.errornormalization and the archive-member constant are addressed. A fresh exact-head review was requested for56c9029588b67f329c334b4e56e1361087f8f651; prior-head reviews, draft skips, and prior-head green checks are not current acceptance evidence.Keep this PR draft. Do not merge, mark ready, enable auto-merge, release, publish, rebase, retarget, force-update, or infer success from missing, queued, failed, prior-head, or draft-skipped checks. Require an auditable credential-separated stack integration followed by exact-current-head Python 3.10–3.13 CI, Ruff, compileall, product-guard self-test, 100% production statement and branch coverage, wheel/sdist package acceptance, applicable SAST and Security Scan, completed automated review, independent non-author approval, branch protection, and every repository policy gate.